import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:hockey/jzx_apps.dart';
import 'package:hockey/services/jzx_user.dart';
import 'package:hockey/widgets/dialogs/jzx_photo_sheet.dart';
import 'package:image_compression/image_compression.dart';
import 'package:path_provider/path_provider.dart' as path_provider;

class JzxEditProfileController extends GetxController {
  TextEditingController nickname = TextEditingController();
  TextEditingController birthday = TextEditingController();
  TextEditingController country = TextEditingController();

  var user = JzxUserService.to.user;

  var enable = false.obs;

  @override
  void onInit() {
    super.onInit();

    nickname.text = JzxUserService.to.nickname;
    birthday.text = JzxUserService.to.birthday;
    country.text = JzxUserService.to.country;
  }

  updateProfile() {
    if (!enable.value) {
      return;
    }

    showLoading();
    JzxNetRepository.client.saveUserInfo({
      'nickname': nickname.text,
      'birthday': birthday.text,
      'country': country.text,
    }).then((value) {
      user.value = user.value.copyWith(
        nickname: nickname.text,
        birthday: birthday.text,
        country: country.text,
      );
      hideLoading();
      showMessage('Edit successfully');
    });
  }

  buttonEnbale() {
    enable.value = (nickname.text.isNotEmpty &&
        birthday.text.isNotEmpty &&
        country.text.isNotEmpty &&
        (nickname.text != JzxUserService.to.nickname ||
            birthday.text != JzxUserService.to.birthday ||
            country.text != JzxUserService.to.country));
  }

  /// 上传
  pickerImage(BuildContext context) async {
    JzxLogPvManger.tracking(page: JzxLogPages.editavatar);

    final res = await JzxPhotoSheet.show(context);

    if (res?.isNotEmpty == true) {
      showLoading();
      final file = await res!.first.file;
      uploadFile(file!, successCallBack: (url) async {
        // 更新用户资料
        final data = await JzxNetRepository.client.updateAvatar({
          'avatarPath': url,
        });
        hideLoading();
        user.value = user.value.copyWith(avatarUrl: data.mediaUrl);
      });
    }
  }

  /// 上传文件
  uploadFile(
    File origin, {
    ValueChanged<String>? successCallBack,
    Function? failedCallBack,
  }) async {
    final file = await compressImage(origin);

    if (file == null) {
      return;
    }

    final data = await JzxNetRepository.client.ossPolicy();

    DateTime dateTime = DateTime.now();
    String fileName = file.path.split('/').last;
    String format = fileName.split('.').last;
    int imageTimeName = dateTime.millisecondsSinceEpoch +
        (dateTime.microsecondsSinceEpoch ~/ 1000000);
    String imageName = '$imageTimeName.$format';
    String host = data!['host'];
    String dir = data!['dir'];
    var filePath = await MultipartFile.fromFile(file.path, filename: fileName);
    final formData = FormData.fromMap({
      'ossaccessKeyId': data!['accessKeyId'],
      'policy': data!['policy'],
      'signature': data!['signature'],
      'callback': data!['callback'],
      'key': '$dir/$imageName',
      'file': filePath,
    });
    Dio dio = Dio();
    var response = await dio.post(host, data: formData);
    if (kDebugMode) {
      print("File Upload Back：$response");
    }
    // print(response);
    if (response.data != null) {
      if (response.data["data"]["filename"] != null) {
        successCallBack?.call(response.data["data"]["filename"]);
      }
    } else {
      failedCallBack?.call();
    }
  }
}

Future<File?> compressImage(File file) async {
  try {
    final input = ImageFile(
      rawBytes: file.readAsBytesSync(),
      filePath: file.path,
    );
    final output = compress(ImageFileConfiguration(
      input: input,
      config: const Configuration(),
    ));

    // print('Input size = ${file.lengthSync()}');
    // print('Output size = ${output.sizeInBytes}');
    final dir = await path_provider.getTemporaryDirectory();
    final targetPath =
        '${dir.absolute.path}/${DateTime.now().millisecondsSinceEpoch}.jpg';

    final res = File(targetPath);

    await res.writeAsBytes(output.rawBytes);

    return res;
  } catch (e) {
    showMessage('compress error: $e');
    return null;
  }
}
